Call Stack
Call Stack
stack frame
activation record
関数呼び出しごとに確保されるメモリ領域
関数の実行時に生成される一時領域
関数のローカル変数や、脱出時の戻り先を保持する記憶領域
winding
あるサブルーチンに関する情報をコールスタックに乗せること
unwinding
あるサブルーチンに関するコールスタックから削除すること
具体例
3種類のレジスタがある
caller-sabe register
callee saved register
special register
C言語では
クロージャのような関数を返す関数を書くことはできない
つまり、コンパイラの実装は単純になる
ML、Scheme、Haskellなどでは
関数を返す関数を書くことが出来る
code:hs
f :: Int -> Int -> Int
f x = \y -> x + y
main = do
let h = f 3 -- ①
let j = f 4 -- ②
print $ h 5 -- 8 -- ③
print $ j 6 -- 10 -- ④
この場合、単純なスタック構造だと
①で3をスタックを積んだ後に、②で4をその上に積むことになるので、
③や④で実際に適用されるときにうまく機能しないことがわかる
①や②で使っているのはどちらも関数fだが、これらの実態は全く別物を見ている
こんな風に、クロージャが書けるような言語ではコンパイラは単純なスタック構造だと無理
なので、コンパイラの実装はより複雑になってしまう
が、言語が柔軟になる
実際どう実装するかは知らんmrsekut.icon
参考
p.116の解説がわかりやすい
図もある